﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SharpMUD.Application.BootStrap;
using SharpMUD.Framework.Services.Telnet;
using System.IO;
using SharpMUD.Framework.Services.Configuration;
using SharpMUD.Framework.IO;
using SharpMUD.Framework.Workflow.Generic;
using SharpMUD.Framework.Net.Telnet;
using SharpMUD.Framework.IO.HumanInterface.Terminal;
using SharpMUD.Framework.Workflow.SessionState;
using SharpMUD.Framework.CorlibExtensions;
using SharpMUD.Framework.Services.Threading;

namespace SharpMUD.Application.DebugHarness
{
    class Program
    {
        protected static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(SharpMUD.Framework.ComponentModel.IService).Assembly,"DebugHarness");

        static void Main(string[] args)
        {
            var appender = new log4net.Appender.ConsoleAppender()
            {
                //Layout = new log4net.Layout.SimpleLayout()
                Layout = new log4net.Layout.PatternLayout("%-5level| %logger{1}> %message%newline"),
            };
            log4net.Config.BasicConfigurator.Configure(
                log4net.LogManager.GetRepository(typeof(SharpMUD.Framework.ComponentModel.IService).Assembly),appender
                );
            //log4net.NDC.Push("");

            bool defaultMudConfigUsed = false;
            Action defaultMudConfigSignaller = delegate()
            {
                log.Warn("\"mud.config\" not loaded - using defaults");
                defaultMudConfigUsed = true;
            };

            var mudConfigPersistanceProxy = PersistanceProxy<MudConfig>.DefaultOrXmlSerializationFile("mud.config", GenerateDefaultMudConfig(), defaultMudConfigSignaller);
            MudServerApplication mudApp = new MudServerApplication(mudConfigPersistanceProxy);

            mudApp.Start();
            Console.WriteLine("Now pulsing...");

            while (mudApp.ExecutionStatus == ExecutionStatusTokens.Running)
            {
                mudApp.Pulse();
                System.Threading.Thread.Sleep(001);
                System.Windows.Forms.Application.DoEvents();
            }

            mudConfigPersistanceProxy.Save(mudApp.GetService<MudConfig>());

            if (mudApp is IDisposable)
                (mudApp as IDisposable).Dispose();
        }

        private static MudConfig GenerateDefaultMudConfig()
        {
            MudConfig defaultMudConfig = new MudConfig();
            defaultMudConfig.Services = new ServiceConfigurationEntryBase[] {
                new BootStrap.InlineServiceConfigurationEntry() {
                    ServiceTypeType = typeof(TelnetServer),
                    ConfigurationText = ToXml(GenerateDefaultTelnetConfig())
                },
                new BootStrap.InlineServiceConfigurationEntry() {
                    ServiceTypeType = typeof(TelnetConnectionAttemptSpamFilter)
                },
                new BootStrap.InlineServiceConfigurationEntry() {
                    ServiceTypeType = typeof(TaskFactoryProviderService)
                }
            };
            return defaultMudConfig;
        }

        private static TelnetServerConfiguration GenerateDefaultTelnetConfig()
        {
            TelnetServerConfiguration telnetConfig = new TelnetServerConfiguration();

            telnetConfig.DefaultSessionStateType = SampleSessionStates<TelnetSession>.DefaultType;
            telnetConfig.MaximumAcceptsPerPulsePerListener = 20;
            telnetConfig.Ports_List.Add(4000);
            
            return telnetConfig;
        }

        private static string ToXml<T>(T config)
            where T : IServiceConfiguration
        {
            StringBuilder sb = new StringBuilder();
            PersistanceProxy<T> configProxy = PersistanceProxy<T>.XmlSerializationString(String.Empty,new StringWriter(sb));
            configProxy.Save(config);
            return sb.ToString();
        }
    }
}
